package gc3d.gridspring;

import gc3d.griddata.GridData;

import java.io.File;
import java.io.IOException;

import org.gridgain.grid.GridFactory;
import org.gridgain.grid.GridNode;


/**
 * @author Pierrick
 *
 */
public class GridPovRender implements GridPov {
	private GridData data;

	public GridPovRender(GridData gd) {
		data = gd;
	}

	//@Override
	public GridData getFile() {
		return data;
	}

	/**
	 * The rendering core executed on each nodes.<br/>
	 * The logic is: 
	 * initProc-createTemp-startRender-copyFiles-notifyDB
	 * @return 0 if the rendering is done, 1 else
	 * @see gc3d.gridspring.GridPov#render()
	 */
	//@Override
	public int render() {
		int povreturnval = 1; // mean error
		GridNode gn = GridFactory.getGrid().getLocalNode();
		//GridNodeMetrics gnm = gn.getMetrics();
		this.data.startJob(gn.getId().toString());

		String povbin = System.getenv("POV_BIN");

		if (povbin == null) {
			System.err.println("[WARN ] You should set/export POV_BIN=/path/to/file/povray/or/megapov/bin/binfile !");

			try {
				// get MegaPOV
				povbin = data.getMegaPOVPath();
				System.out.println("[INFO ] MegaPOV deployed, using `"+povbin+"` as command");
			} catch (Exception e) {
				System.err.println("[ERROR] Error while getting MegaPOV !");
				povbin = "megapov";
				System.out.println("[WARN ] Using `megapov` as command, PATH must be up to date");
			}
		}

		try {
			File workdir = data.writeLocal();
			ProcessBuilder pb = new ProcessBuilder(povbin, data.getININame());
			System.out.println("[INFO ] using `"+povbin+' '+data.getININame()+"` as command");

			// link stderr and stdout to read them to prevent pipe-overflow
			pb.redirectErrorStream(true);

			pb.directory(workdir);
			System.out.println(this+".render (0) start "+data.getININame());
			this.data.updateJobStatus("start "+povbin+' '+data.getININame());
			Process p = pb.start(); // Here: POV-Ray is runing
			// we have to read the buffer
			new Thread(new ProcReceiver(p.getInputStream())).start();
			povreturnval = p.waitFor(); // should be 0
		} catch (IOException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(this+".render (1) finish "+data.getININame());
		this.data.updateJobStatus("finish");

		if (povreturnval == 0) {
			povreturnval = 1;
			try {
				if (data.writeRemotePNG()) {
					// if we succed, we return no error
					povreturnval = 0;
					this.data.updateJobStatus("finish & sent");
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			System.err.println("[ERROR] Rendering [POV-Ray] error !");
		}
		this.data.finishJob();

		return povreturnval;
	}
}
